#include "map_background_item.h"
#include <QDebug>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QPainterPath>
#include <QSettings>
#include <QCoreApplication>
#include <QDir>

namespace {

QString normalizeMapName(const QString& name)
{
    QString normalized = name.trimmed();
    if (normalized.isEmpty()) {
        return normalized;
    }

    int slashIndex = normalized.lastIndexOf('/');
    int backslashIndex = normalized.lastIndexOf('\\');
    int separator = slashIndex;
    if (backslashIndex > separator) {
        separator = backslashIndex;
    }
    if (separator != -1) {
        normalized = normalized.mid(separator + 1);
    }

    int dotIndex = normalized.lastIndexOf('.');
    if (dotIndex > 0) {
        normalized = normalized.left(dotIndex);
    }

    return normalized.toLower();
}

bool matchesActiveMap(const QString& normalizedTarget, const QString& candidate)
{
    if (normalizedTarget.isEmpty()) {
        return true;
    }

    const QString normalizedCandidate = normalizeMapName(candidate);
    if (normalizedCandidate.isEmpty()) {
        return false;
    }

    return normalizedCandidate == normalizedTarget;
}

}  // namespace

namespace presentation {

MapBackgroundItem::MapBackgroundItem(QQuickItem* parent)
    : QQuickPaintedItem(parent)
{
    // Set up mouse event handling (matching reference)
    setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton);
    setFlag(ItemAcceptsInputMethod, true);

    // 加载配置
    loadConfig();

    // Initialize transforms (matching reference)
    rebuildBaseTransform();

    scaleTransform_.reset();
    scaleTransform_.scale(config_.defaultScale, config_.defaultScale);

    mouseMoveTransform_.reset();

    // 移除定时器，改为按需更新机制
    // 预渲染背景将在数据加载时自动生成

    setFillColor(Qt::gray);

}

// Destructor is default, no need to implement

bool MapBackgroundItem::initMap(const QString& mapName)
{
    // Check if map is already loaded
    if (mapLoadSuccess_ && mapData_.mapName == mapName) {
        return true;
    }
    
    mapLoadSuccess_ = false;
    update();
    
    // Load map data (this would normally come from MapService)
    // For now, we'll use the existing mapData_ if it matches
    if (mapData_.mapName != mapName) {
        qWarning() << "MapBackgroundItem: Map" << mapName << "not available in current data";
        return false;
    }
    
    // Load transform parameters from settings (matching reference)
    loadTransformParams();
    
    mapLoadSuccess_ = true;
    updateMapPos();
    update();
    
    return true;
}

void MapBackgroundItem::saveTransformParams()
{
    if (!mapLoadSuccess_) return;
    
    QSettings settings(QCoreApplication::applicationDirPath() + "/app_config.ini", QSettings::IniFormat);
    settings.beginGroup(mapData_.mapName);
    settings.setValue("map_transform.dx", mouseMoveTransform_.dx());
    settings.setValue("map_transform.dy", mouseMoveTransform_.dy());
    settings.setValue("map_transform.scale", scaleTransform_.m22());
    settings.endGroup();
}

void MapBackgroundItem::loadTransformParams()
{
    if (!mapLoadSuccess_) return;
    
    QSettings settings(QCoreApplication::applicationDirPath() + "/app_config.ini", QSettings::IniFormat);
    settings.beginGroup(mapData_.mapName);
    
    double dx = settings.value("map_transform.dx", -1).toDouble();
    double dy = settings.value("map_transform.dy", -1).toDouble();
    double scale = settings.value("map_transform.scale", -1).toDouble();
    
    settings.endGroup();
    
    // Apply loaded parameters
    if (dx != -1 && dy != -1) {
        mouseMoveTransform_.reset();
        mouseMoveTransform_.translate(dx, dy);
    }
    
    if (scale != -1) {
        config_.defaultScale = scale;
        scaleTransform_.reset();
        scaleTransform_.scale(config_.defaultScale, config_.defaultScale);
    }
    
    qDebug() << "MapBackgroundItem: Loaded transform parameters - dx:" << dx << "dy:" << dy << "scale:" << scale;
}

void MapBackgroundItem::updateMapPos()
{
    if (!mapLoadSuccess_) return;
    
    QPointF maxPos = QPointF(mapData_.bounds.right(), mapData_.bounds.bottom());
    maxPos = pointTransform(maxPos);
    QPointF minPos = QPointF(mapData_.bounds.left(), mapData_.bounds.top());
    minPos = pointTransform(minPos);
    
    setMapWidth(static_cast<int>(maxPos.x() - minPos.x()));
    setMapHeight(static_cast<int>(maxPos.y() - minPos.y()));
}

void MapBackgroundItem::setMapWidth(int width)
{
    if (mapWidth_ == width) return;
    mapWidth_ = width;
    emit mapWidthChanged();
}

void MapBackgroundItem::setMapHeight(int height)
{
    if (mapHeight_ == height) return;
    mapHeight_ = height;
    emit mapHeightChanged();
}

QPointF MapBackgroundItem::pointTransform(const QPointF& point) const
{
    return mouseMoveTransform_.map(scaleTransform_.map(moveTransform_.map(point)));
}

// 变换缓存管理实现
void MapBackgroundItem::invalidateCache() const
{
    cacheValid_ = false;
    transformedPointsCache_.clear();

    // 预渲染背景失效需要在非const上下文中处理
    // 这里只标记缓存失效，实际的预渲染背景失效在paint()等方法中处理
}

bool MapBackgroundItem::isCacheValid() const
{
    if (!cacheValid_) return false;
    
    // 检查变换是否发生变化
    QTransform currentTransform = mouseMoveTransform_ * scaleTransform_ * moveTransform_;
    return currentTransform == lastTransform_;
}

QPointF MapBackgroundItem::getCachedTransform(int index, const QPointF& originalPoint) const
{
    if (!isCacheValid()) {
        invalidateCache();
        lastTransform_ = mouseMoveTransform_ * scaleTransform_ * moveTransform_;
        cacheValid_ = true;
    }
    
    if (transformedPointsCache_.contains(index)) {
        return transformedPointsCache_[index];
    }
    
    QPointF transformed = pointTransform(originalPoint);
    transformedPointsCache_[index] = transformed;
    return transformed;
}



// 安全检查方法实现
bool MapBackgroundItem::isValidIndex(int index, size_t containerSize) const
{
    return index >= 0 && static_cast<size_t>(index) < containerSize;
}

bool MapBackgroundItem::hasValidPoints(const QVector<QPointF>& points) const
{
    return !points.isEmpty() && points.size() >= 2;
}

bool MapBackgroundItem::isPointInBounds(const QPointF& point) const
{
    if (!mapLoadSuccess_) return false;
    
    const QRectF& bounds = mapData_.bounds;
    return point.x() >= bounds.left() && point.x() <= bounds.right() &&
           point.y() >= bounds.top() && point.y() <= bounds.bottom();
}

// 配置管理实现
void MapBackgroundItem::loadConfig()
{
    QSettings settings(QCoreApplication::applicationDirPath() + "/map_drawing_config.ini", QSettings::IniFormat);
    settings.beginGroup("MapDrawing");
    
    // 加载颜色配置
    config_.backgroundColor = settings.value("backgroundColor", config_.backgroundColor).value<QColor>();
    config_.stationColor = settings.value("stationColor", config_.stationColor).value<QColor>();
    config_.pathColor = settings.value("pathColor", config_.pathColor).value<QColor>();
    config_.areaColor = settings.value("areaColor", config_.areaColor).value<QColor>();
    config_.normalPointColor = settings.value("normalPointColor", config_.normalPointColor).value<QColor>();
    config_.stationBorderColor = settings.value("stationBorderColor", config_.stationBorderColor).value<QColor>();
    
    // 加载尺寸配置
    config_.stationSize = settings.value("stationSize", config_.stationSize).toDouble();
    config_.pathWidth = settings.value("pathWidth", config_.pathWidth).toDouble();
    config_.scaleFactor = settings.value("scaleFactor", config_.scaleFactor).toDouble();
    config_.normalPointSize = settings.value("normalPointSize", config_.normalPointSize).toDouble();
    
    // 加载性能配置
    config_.normalPointSampleRate = settings.value("normalPointSampleRate", config_.normalPointSampleRate).toInt();
    config_.minScaleForStationText = settings.value("minScaleForStationText", config_.minScaleForStationText).toDouble();
    
    // 加载变换配置
    config_.defaultScale = settings.value("defaultScale", config_.defaultScale).toDouble();
    config_.zoomFactor = settings.value("zoomFactor", config_.zoomFactor).toDouble();
    
    // 加载字体配置
    config_.stationFontFamily = settings.value("stationFontFamily", config_.stationFontFamily).toString();
    config_.stationFontSize = settings.value("stationFontSize", config_.stationFontSize).toInt();
    
    settings.endGroup();
    
    qDebug() << "MapBackgroundItem: Configuration loaded";
}

void MapBackgroundItem::saveConfig()
{
    QSettings settings(QCoreApplication::applicationDirPath() + "/map_drawing_config.ini", QSettings::IniFormat);
    settings.beginGroup("MapDrawing");
    
    // 保存颜色配置
    settings.setValue("backgroundColor", config_.backgroundColor);
    settings.setValue("stationColor", config_.stationColor);
    settings.setValue("pathColor", config_.pathColor);
    settings.setValue("areaColor", config_.areaColor);
    settings.setValue("normalPointColor", config_.normalPointColor);
    settings.setValue("stationBorderColor", config_.stationBorderColor);
    
    // 保存尺寸配置
    settings.setValue("stationSize", config_.stationSize);
    settings.setValue("pathWidth", config_.pathWidth);
    settings.setValue("scaleFactor", config_.scaleFactor);
    settings.setValue("normalPointSize", config_.normalPointSize);
    
    // 保存性能配置
    settings.setValue("normalPointSampleRate", config_.normalPointSampleRate);
    settings.setValue("minScaleForStationText", config_.minScaleForStationText);
    
    // 保存变换配置
    settings.setValue("defaultScale", config_.defaultScale);
    settings.setValue("zoomFactor", config_.zoomFactor);
    
    // 保存字体配置
    settings.setValue("stationFontFamily", config_.stationFontFamily);
    settings.setValue("stationFontSize", config_.stationFontSize);
    
    settings.endGroup();
    
    qDebug() << "MapBackgroundItem: Configuration saved";
}

void MapBackgroundItem::resetToDefaultConfig()
{
    config_ = MapDrawingConfig();  // 使用默认值重置
    qDebug() << "MapBackgroundItem: Configuration reset to defaults";
}

QPointF MapBackgroundItem::mouseTransformPoint(const QPointF& point) const
{
    return moveTransform_.inverted().map(scaleTransform_.inverted().map(mouseMoveTransform_.inverted().map(point)));
}

void MapBackgroundItem::drawBezierCurve(QPainter* painter, const QPointF& start, const QPointF& end,
                                       const QPointF& control1, const QPointF& control2, const QColor& color)
{
    QPainterPath path;
    path.moveTo(start);
    path.cubicTo(control1, control2, end);
    
    painter->setPen(createPathPen(color, config_.pathWidth, Qt::DashLine));
    painter->drawPath(path);
}

// 公共绘制工具方法实现
QPen MapBackgroundItem::createPathPen(const QColor& color, double width, Qt::PenStyle style) const
{
    QPen pen;
    pen.setWidth(static_cast<int>(width > 0 ? width : config_.pathWidth));
    pen.setColor(color);
    pen.setStyle(style);
    return pen;
}

void MapBackgroundItem::setupPainter(QPainter* painter) const
{
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->resetTransform();
}

void MapBackgroundItem::drawBezierPaths(QPainter* painter)
{
    setupPainter(painter);
    
    for (const auto& path : mapData_.paths) {
        if (path.pathType != "bezier" || !hasValidPoints(path.points)) continue;
        
        QPointF startPoint = pointTransform(path.points.first());
        QPointF endPoint = pointTransform(path.points.last());
        
        // For bezier curves, we need control points
        // Using simplified approach - create control points based on path points
        QPointF control1, control2;
        if (path.points.size() >= 3) {
            control1 = pointTransform(path.points[1]);
            control2 = pointTransform(path.points[2]);
        } else {
            // Create default control points
            QPointF mid = (startPoint + endPoint) / 2;
            control1 = startPoint + (mid - startPoint) * 0.5;
            control2 = endPoint + (mid - endPoint) * 0.5;
        }
        
        drawBezierCurve(painter, startPoint, endPoint, control1, control2, config_.pathColor);
    }
}

void MapBackgroundItem::drawArcPaths(QPainter* painter)
{
    setupPainter(painter);
    
    for (const auto& path : mapData_.paths) {
        if (path.pathType != "arc" || !hasValidPoints(path.points)) continue;
        
        QPointF startPoint = pointTransform(path.points.first());
        QPointF endPoint = pointTransform(path.points.last());
        
        QPainterPath arcPath;
        arcPath.moveTo(startPoint);
        
        if (path.points.size() >= 2) {
            QPointF controlPoint = pointTransform(path.points[1]);
            arcPath.quadTo(controlPoint, endPoint); 
        } else {
            arcPath.lineTo(endPoint);
        }
        
        painter->setPen(createPathPen(config_.pathColor, config_.pathWidth, Qt::DashLine));
        painter->drawPath(arcPath);
    }
}

void MapBackgroundItem::drawStraightPaths(QPainter* painter)
{
    setupPainter(painter);
    
    for (const auto& path : mapData_.paths) {
        if (path.pathType != "straight" || !hasValidPoints(path.points)) continue;
        
        QPointF startPoint = pointTransform(path.points.first());
        QPointF endPoint = pointTransform(path.points.last());
        
        painter->setPen(createPathPen(config_.pathColor, config_.pathWidth));
        painter->drawLine(startPoint, endPoint);
    }
}

void MapBackgroundItem::drawAdvancedPoints(QPainter* painter)
{
    setupPainter(painter);
    
    for (const auto& station : mapData_.stations) {
        QPointF point = pointTransform(station.position);
        
        painter->translate(point.x(), point.y());
        painter->rotate(-station.direction / 3.1415926 * 180);
        
        qreal width = config_.stationSize * scaleTransform_.m11();
        qreal height = config_.stationSize * scaleTransform_.m11();
        qreal x = -width / 2;
        qreal y = -height / 2;
        QRect rect(x, y, width, height);
        
        // Set color based on station type (matching reference)
        QColor fillColor = getStationColorByType(station.className, station.stationType);
        painter->fillRect(rect, fillColor);
        
        // Draw border
        if (abs(scaleTransform_.m11()) > config_.minScaleForStationText) {
            painter->setPen(createPathPen(config_.stationBorderColor, 4, Qt::DashLine));
            painter->drawRect(rect);
            
            // Draw station name
            painter->rotate(station.direction / 3.1415926 * 180);  // Reverse rotation for text
            painter->setPen(Qt::black);
            painter->setFont(QFont(config_.stationFontFamily, config_.stationFontSize));
            painter->drawText(rect, Qt::AlignHCenter | Qt::AlignVCenter, station.name);
        } else {
            painter->setPen(createPathPen(config_.stationBorderColor, 1, Qt::DashLine));
            painter->drawRect(rect);
        }
        
        painter->resetTransform();
    }
}

void MapBackgroundItem::drawNormalPoints(QPainter* painter)
{
    setupPainter(painter);
    
    // Draw obstacle points (simplified version)
    QColor color = config_.normalPointColor;
    
    // Sample every nth point for performance (matching reference)
    for (int i = 0; i < mapData_.normalPoints.size(); i += config_.normalPointSampleRate) {
        if (!isValidIndex(i, mapData_.normalPoints.size())) continue;
        
        QPointF point = getCachedTransform(i, mapData_.normalPoints[i]);
        QRect rect(point.x(), point.y(), static_cast<int>(config_.normalPointSize), static_cast<int>(config_.normalPointSize));
        painter->fillRect(rect, color);
    }
}

void MapBackgroundItem::drawAdvancedAreas(QPainter* painter)
{
    setupPainter(painter);
    
    for (int i = 0; i < mapData_.areas.size(); ++i) {
        const auto& area = mapData_.areas[i];
        if (area.points.size() < 3) continue;  // 至少需要3个点形成多边形
        
        // 创建多边形路径
        QPainterPath polygonPath;
        QPointF firstPoint = pointTransform(area.points[0]);
        polygonPath.moveTo(firstPoint);
        
        for (int j = 1; j < area.points.size(); ++j) {
            QPointF point = pointTransform(area.points[j]);
            polygonPath.lineTo(point);
        }
        polygonPath.closeSubpath();
        
        // 设置透明填充颜色
        QColor fillColor = area.fillColor;
        fillColor.setAlpha(static_cast<int>(area.opacity * 255));  // 使用区域配置的透明度
        
        // 绘制透明填充
        painter->fillPath(polygonPath, fillColor);
        
        // 绘制边框
        QPen borderPen;
        borderPen.setColor(area.borderColor);
        borderPen.setWidth(2);
        painter->setPen(borderPen);
        painter->drawPath(polygonPath);
        
        // 在区域中心显示名称
        if (area.showName) {
            QPointF center = polygonPath.boundingRect().center();
            QString areaName = area.name.isEmpty() ? QString("区域%1").arg(i + 1) : area.name;
            
            // 设置文字样式
            painter->setPen(Qt::black);
            painter->setFont(QFont("Arial", 12, QFont::Bold));
            
            // 绘制文字背景（白色半透明）
            QFontMetrics fm(painter->font());
            QRect textRect = fm.boundingRect(areaName);
            textRect.moveCenter(center.toPoint());
            textRect.adjust(-4, -2, 4, 2);
            
            QColor textBgColor = Qt::white;
            textBgColor.setAlpha(180);
            painter->fillRect(textRect, textBgColor);
            
            // 绘制文字
            painter->drawText(textRect, Qt::AlignCenter, areaName);
        }
    }
}

void MapBackgroundItem::drawMapBackground(QPainter* painter)
{
    setupPainter(painter);
    
    // Draw background respecting current axis inversion
    QPointF topLeft = pointTransform(QPointF(mapData_.bounds.left(), mapData_.bounds.top()));
    QPointF bottomRight = pointTransform(QPointF(mapData_.bounds.right(), mapData_.bounds.bottom()));

    QRectF rect(QPointF(qMin(topLeft.x(), bottomRight.x()),
                        qMin(topLeft.y(), bottomRight.y())),
                QPointF(qMax(topLeft.x(), bottomRight.x()),
                        qMax(topLeft.y(), bottomRight.y())));

    painter->fillRect(rect.normalized(), config_.backgroundColor);
    
    painter->resetTransform();
}

QColor MapBackgroundItem::getStationColorByType(const QString& className, const QString& stationType) const
{
    // Color mapping matching reference implementation
    if (className == "LocationMark") {
        return QColor("#C9F970");
    } else if (className == "ActionPoint") {
        return QColor("#F2A577");
    }
    
    if (stationType == "Charge") {
        return QColor("#FFF577");
    } else if (stationType == "Park") {
        return QColor("#a528ae");
    }
    
    return config_.stationColor;
}

void MapBackgroundItem::clickStation(const QPointF& pos)
{
    for (const auto& station : mapData_.stations) {
        QPointF point = pointTransform(station.position);
        
        qreal width = config_.stationSize * scaleTransform_.m11();
        qreal height = config_.stationSize * scaleTransform_.m11();
        qreal x = point.x() - width / 2;
        qreal y = point.y() - height / 2;
        QRect rect(x, y, width, height);
        
        if (rect.contains(pos.toPoint())) {
            qDebug() << "MapBackgroundItem: Station clicked:" << station.name;
            emit stationClicked(station.name, station.position);
            return;
        }
    }
}

void MapBackgroundItem::paint(QPainter* painter)
{
    if (!mapLoadSuccess_) return;

    // 统一设置绘制器（抗锯齿等）
    setupPainter(painter);

    // 传统逐层绘制方式
    drawMapBackground(painter);
    // drawNormalPoints(painter);
    drawBezierPaths(painter);
    drawArcPaths(painter);
    drawStraightPaths(painter);
    drawAdvancedPoints(painter);
    drawAdvancedAreas(painter);

    // 绘制 AGV 层（最上层）
    drawAgvLayer(painter);
}

void MapBackgroundItem::mousePressEvent(QMouseEvent* event)
{
    event->accept();

    switch (event->button()) {
    case Qt::LeftButton:
    {
        QPointF pos = event->localPos();

        // 先检测 AGV 点击
        clickAgv(pos);

        // 再检测站点点击
        clickStation(pos);

        // 发送通用点击信号
        emit singleClick(pos);
    }
    break;
    case Qt::RightButton:
    {
        mousePressPos_ = event->localPos();
        isDragging_ = true;
    }
    break;
    default:
        break;
    }
}

void MapBackgroundItem::mouseMoveEvent(QMouseEvent* event)
{
    event->accept();

    if (isDragging_ && (event->buttons() & Qt::RightButton) == Qt::RightButton) {
        QPointF pos = event->localPos();
        mouseMoveTransform_.translate(pos.x() - mousePressPos_.x(), pos.y() - mousePressPos_.y());
        mousePressPos_ = event->localPos();
        invalidateCache();  // 变换变化时使缓存失效

        update();
    }
}

void MapBackgroundItem::mouseReleaseEvent(QMouseEvent* event)
{
    event->accept();
    
    switch (event->button()) {
    case Qt::LeftButton:
        break;
    case Qt::RightButton:
    {
        isDragging_ = false;
        // Save transform parameters (matching reference)
        saveTransformParams();
        update();
    }
    break;
    default:
        break;
    }
}

void MapBackgroundItem::wheelEvent(QWheelEvent* event)
{
    event->accept();

    QPointF pos = event->position();
    QPoint scroll = event->angleDelta();

    if (scroll.y() > 0) {
        // Zoom in
        QPointF invertPos = mouseTransformPoint(pos);
        scaleTransform_.scale(config_.zoomFactor, config_.zoomFactor);
        QPointF scalePos = pointTransform(invertPos);
        mouseMoveTransform_.translate(-(scalePos.x() - pos.x()), -(scalePos.y() - pos.y()));
    } else {
        // Zoom out
        QPointF invertPos = mouseTransformPoint(pos);
        scaleTransform_.scale(pow(config_.zoomFactor, -1), pow(config_.zoomFactor, -1));
        QPointF scalePos = pointTransform(invertPos);
        mouseMoveTransform_.translate(pos.x() - scalePos.x(), pos.y() - scalePos.y());
    }

    invalidateCache();  // 缩放变化时使缓存失效

    update();
}

// 移除定时器更新方法，改为按需更新

// Property setters
void MapBackgroundItem::setMapData(const kernel::MapDisplayDto& data)
{
    bool dataChanged = mapData_.mapName != data.mapName ||
                      mapData_.bounds != data.bounds ||
                      mapData_.stations.size() != data.stations.size() ||
                      mapData_.paths.size() != data.paths.size() ||
                      mapData_.normalPoints.size() != data.normalPoints.size();

    if (!dataChanged) return;

    mapData_ = data;
    mapLoadSuccess_ = !data.mapName.isEmpty();

    if (mapLoadSuccess_) {
        updateMapPos();
        loadTransformParams();
    }

    emit mapDataChanged();
    update();
}

void MapBackgroundItem::setAgvListModel(QAbstractListModel* model)
{
    if (agvListModel_ == model) return;

    // 断开旧模型的信号
    if (agvListModel_) {
        disconnectAgvModelSignals();
    }

    agvListModel_ = model;

    // 连接新模型的信号
    if (agvListModel_) {
        connectAgvModelSignals();
    }

    emit agvListModelChanged();
    update();  // 触发重绘
}

void MapBackgroundItem::setShowAgvLabels(bool show)
{
    if (showAgvLabels_ == show) return;
    showAgvLabels_ = show;
    emit showAgvLabelsChanged();
    update();
}

void MapBackgroundItem::setAgvIconSize(double size)
{
    if (qFuzzyCompare(agvIconSize_, size)) return;
    agvIconSize_ = size;
    emit agvIconSizeChanged();
    update();
}

void MapBackgroundItem::setFilterAgvByMap(bool filter)
{
    if (filterAgvByMap_ == filter) return;
    filterAgvByMap_ = filter;
    emit filterAgvByMapChanged();
    update();
}

void MapBackgroundItem::setBackgroundColor(const QColor& color)
{
    if (config_.backgroundColor == color) return;
    config_.backgroundColor = color;
    emit backgroundColorChanged();
    update();
}

void MapBackgroundItem::setStationColor(const QColor& color)
{
    if (config_.stationColor == color) return;
    config_.stationColor = color;
    emit stationColorChanged();
    update();
}

void MapBackgroundItem::setPathColor(const QColor& color)
{
    if (config_.pathColor == color) return;
    config_.pathColor = color;
    emit pathColorChanged();
    update();
}

void MapBackgroundItem::setAreaColor(const QColor& color)
{
    if (config_.areaColor == color) return;
    config_.areaColor = color;
    emit areaColorChanged();
    update();
}

void MapBackgroundItem::setStationSize(double size)
{
    if (qFuzzyCompare(config_.stationSize, size)) return;
    config_.stationSize = size;
    emit stationSizeChanged();
    update();
}

void MapBackgroundItem::setPathWidth(double width)
{
    if (qFuzzyCompare(config_.pathWidth, width)) return;
    config_.pathWidth = width;
    emit pathWidthChanged();
    update();
}

void MapBackgroundItem::setScaleFactor(double factor)
{
    if (qFuzzyCompare(config_.scaleFactor, factor)) return;
    config_.scaleFactor = factor;
    emit scaleFactorChanged();
    update();
}

void MapBackgroundItem::setPanOffset(const QPointF& offset)
{
    if (panOffset_ == offset) return;
    panOffset_ = offset;
    emit panOffsetChanged();
    update();
}

void MapBackgroundItem::rebuildBaseTransform()
{
    moveTransform_.reset();
    // Mirror both axes so Y axis is inverted as requested
    moveTransform_.scale(1, -1);
}

// Utility methods
QPointF MapBackgroundItem::screenToMap(const QPointF& screenPoint) const
{
    return mouseTransformPoint(screenPoint);
}

QPointF MapBackgroundItem::mapToScreen(const QPointF& mapPoint) const
{
    return pointTransform(mapPoint);
}

void MapBackgroundItem::resetView()
{
    rebuildBaseTransform();

    scaleTransform_.reset();
    scaleTransform_.scale(config_.defaultScale, config_.defaultScale);

    mouseMoveTransform_.reset();

    invalidateCache();  // 重置视图时使缓存失效
    update();
}

void MapBackgroundItem::fitToView()
{
    if (!mapLoadSuccess_) return;

    // Calculate scale to fit map in view
    QSizeF itemSize = size();
    QRectF mapBounds = mapData_.bounds;

    double scaleX = itemSize.width() / mapBounds.width();
    double scaleY = itemSize.height() / mapBounds.height();
    double scale = qMin(scaleX, scaleY) * 0.9;  // 90% to leave some margin

    scaleTransform_.reset();
    scaleTransform_.scale(scale, scale);

    // Center the map
    QPointF mapCenter = pointTransform(mapBounds.center());
    QPointF viewCenter(itemSize.width() / 2, itemSize.height() / 2);
    mouseMoveTransform_.translate(viewCenter.x() - mapCenter.x(), viewCenter.y() - mapCenter.y());

    update();
}

void MapBackgroundItem::centerOnPoint(const QPointF& mapPoint, double scale)
{
    if (!mapLoadSuccess_) return;

    QSizeF itemSize = size();

    // Apply scale if specified, otherwise keep current scale
    if (scale > 0) {
        scaleTransform_.reset();
        scaleTransform_.scale(scale, scale);
    }

    // Calculate current screen position of the target point
    QPointF screenPos = pointTransform(mapPoint);

    // Calculate view center
    QPointF viewCenter(itemSize.width() / 2, itemSize.height() / 2);

    // Translate to center the point
    mouseMoveTransform_.translate(viewCenter.x() - screenPos.x(), viewCenter.y() - screenPos.y());

    invalidateCache();
    saveTransformParams();
    update();
}

// ============ AGV 绘制相关实现 ============

void MapBackgroundItem::connectAgvModelSignals()
{
    if (!agvListModel_) return;

    // 连接模型变化信号，触发重绘
    connect(agvListModel_, &QAbstractListModel::dataChanged,
            this, [this]() { update(); });
    connect(agvListModel_, &QAbstractListModel::rowsInserted,
            this, [this]() { update(); });
    connect(agvListModel_, &QAbstractListModel::rowsRemoved,
            this, [this]() { update(); });
    connect(agvListModel_, &QAbstractListModel::modelReset,
            this, [this]() { update(); });
}

void MapBackgroundItem::disconnectAgvModelSignals()
{
    if (!agvListModel_) return;

    disconnect(agvListModel_, nullptr, this, nullptr);
}

void MapBackgroundItem::drawAgvLayer(QPainter* painter)
{
    if (!agvListModel_ || !mapLoadSuccess_) return;

    int rowCount = agvListModel_->rowCount();
    if (rowCount == 0) return;

    // 获取 Model 的角色名称
    QHash<int, QByteArray> roleNames = agvListModel_->roleNames();
    int agvNumberRole = roleNames.key("agvNumber", -1);
    int nameRole = roleNames.key("name", -1);
    int xRole = roleNames.key("x", -1);
    int yRole = roleNames.key("y", -1);
    int angleRole = roleNames.key("angle", -1);
    int isOnlineRole = roleNames.key("isOnline", -1);
    int isChargingRole = roleNames.key("isCharging", -1);
    int isControlledRole = roleNames.key("isControlled", -1);
    int isBlockedRole = roleNames.key("isBlocked", -1);
    int isLockedRole = roleNames.key("isLocked", -1);
    int statusTagsRole = roleNames.key("statusTags", -1);
    int currentMapRole = roleNames.key("currentMap", -1);

    const bool filterEnabled =
        filterAgvByMap_ && currentMapRole != -1 && !mapData_.mapName.isEmpty();
    const QString normalizedActiveMap =
        filterEnabled ? normalizeMapName(mapData_.mapName) : QString();

    // 遍历所有 AGV
    for (int i = 0; i < rowCount; ++i) {
        QModelIndex index = agvListModel_->index(i, 0);

        // 获取 AGV 数据
        int agvNumber = agvListModel_->data(index, agvNumberRole).toInt();
        QString name = agvListModel_->data(index, nameRole).toString();
        double x = agvListModel_->data(index, xRole).toDouble();
        double y = agvListModel_->data(index, yRole).toDouble();
        double angle = agvListModel_->data(index, angleRole).toDouble();
        bool isOnline = agvListModel_->data(index, isOnlineRole).toBool();
        bool isCharging = agvListModel_->data(index, isChargingRole).toBool();
        bool isControlled = agvListModel_->data(index, isControlledRole).toBool();
        bool isBlocked = isBlockedRole != -1 ? agvListModel_->data(index, isBlockedRole).toBool() : false;
        bool isLocked = isLockedRole != -1 ? agvListModel_->data(index, isLockedRole).toBool() : false;
        QStringList statusTags = statusTagsRole != -1
                                     ? agvListModel_->data(index, statusTagsRole).toStringList()
                                     : QStringList();
        QString agvMapName = currentMapRole != -1
                                 ? agvListModel_->data(index, currentMapRole).toString()
                                 : QString();

        // 跳过离线或无效位置的 AGV
        if (!isOnline || (qFuzzyIsNull(x) && qFuzzyIsNull(y))) {
            continue;
        }

        if (!matchesActiveMap(normalizedActiveMap, agvMapName)) {
            continue;
        }

        // 将地图坐标转换为屏幕坐标
        QPointF mapPos(x, y);
        QPointF screenPos = pointTransform(mapPos);

        // 确定 AGV 状态颜色
        QColor statusColor = getAgvStatusColor(isOnline, isCharging, isControlled, isBlocked, isLocked);

        // 绘制 AGV 图标
        drawAgvIcon(painter, screenPos, angle, statusColor, agvIconSize_);

        // 绘制 AGV 标签
        if (showAgvLabels_) {
            QString label = name.isEmpty() ? QString("AGV %1").arg(agvNumber) : name;
            if (!statusTags.isEmpty()) {
                label += QStringLiteral(" [") + statusTags.join(QStringLiteral("/")) + QStringLiteral("]");
            }
            drawAgvLabel(painter, screenPos, label);
        }
    }
}

QColor MapBackgroundItem::getAgvStatusColor(bool isOnline, bool isCharging, bool isControlled,
                                            bool isBlocked, bool isLocked) const
{
    if (!isOnline) return QColor("#808080");  // 灰色-离线
    if (isLocked) return QColor("#9E9E9E");   // 灰-锁定/急停
    if (isBlocked) return QColor("#FF5252");  // 红色-阻挡
    if (isCharging) return QColor("#FFA500");  // 橙色-充电中
    if (isControlled) return QColor("#1E90FF");  // 蓝色-执行中
    return QColor("#32CD32");  // 绿色-空闲
}

void MapBackgroundItem::drawAgvIcon(QPainter* painter, const QPointF& position, double angle,
                                     const QColor& color, double size) const
{
    painter->save();

    // 移动到 AGV 位置
    painter->translate(position);

    // 旋转到 AGV 朝向
    double agv_rotate = -angle / 3.1415926 * 180;// 负号是因为 Qt 的旋转方向
    painter->rotate(agv_rotate);

    // 绘制 AGV 图标（简单的三角形表示）
    double halfSize = size / 2.0;
    QPointF points[3] = {
        QPointF(halfSize * 1.25, 0),            // Front point (沿X轴指向前方)
        QPointF(-halfSize, halfSize * 0.75),   // Upper rear corner
        QPointF(-halfSize, -halfSize * 0.75)   // Lower rear corner
    };

    // 绘制填充三角形
    painter->setBrush(color);
    painter->setPen(QPen(Qt::black, 2));
    painter->drawPolygon(points, 3);

    // 绘制方向指示线
    painter->setPen(QPen(Qt::white, 2));
    painter->drawLine(QPointF(0, 0), QPointF(halfSize, 0));

    painter->restore();
}

void MapBackgroundItem::drawAgvLabel(QPainter* painter, const QPointF& position, const QString& label) const
{
    painter->save();

    // 设置字体
    QFont font = painter->font();
    font.setPointSize(10);
    font.setBold(true);
    painter->setFont(font);

    // 计算文本位置（图标下方）
    QFontMetrics metrics(font);
    int textWidth = metrics.horizontalAdvance(label);
    int textHeight = metrics.height();

    QPointF textPos(position.x() - textWidth / 2.0,
                    position.y() + agvIconSize_ / 2.0 + textHeight + 5);

    // 绘制文本背景
    QRectF textRect(textPos.x() - 3, textPos.y() - textHeight, textWidth + 6, textHeight + 3);
    painter->setBrush(QColor(0, 0, 0, 180));
    painter->setPen(Qt::NoPen);
    painter->drawRoundedRect(textRect, 3, 3);

    // 绘制文本
    painter->setPen(Qt::white);
    painter->drawText(textPos, label);

    painter->restore();
}

void MapBackgroundItem::clickAgv(const QPointF& pos)
{
    if (!agvListModel_ || !mapLoadSuccess_) return;

    int rowCount = agvListModel_->rowCount();
    QHash<int, QByteArray> roleNames = agvListModel_->roleNames();
    int agvNumberRole = roleNames.key("agvNumber", -1);
    int xRole = roleNames.key("x", -1);
    int yRole = roleNames.key("y", -1);
    int isOnlineRole = roleNames.key("isOnline", -1);
    int currentMapRole = roleNames.key("currentMap", -1);

    const bool filterEnabled =
        filterAgvByMap_ && currentMapRole != -1 && !mapData_.mapName.isEmpty();
    const QString normalizedActiveMap =
        filterEnabled ? normalizeMapName(mapData_.mapName) : QString();

    double clickRadius = agvIconSize_;  // 点击检测半径

    for (int i = 0; i < rowCount; ++i) {
        QModelIndex index = agvListModel_->index(i, 0);

        int agvNumber = agvListModel_->data(index, agvNumberRole).toInt();
        double x = agvListModel_->data(index, xRole).toDouble();
        double y = agvListModel_->data(index, yRole).toDouble();
        bool isOnline = agvListModel_->data(index, isOnlineRole).toBool();
        QString agvMapName = currentMapRole != -1
                                 ? agvListModel_->data(index, currentMapRole).toString()
                                 : QString();

        if (!isOnline) continue;
        if (!matchesActiveMap(normalizedActiveMap, agvMapName)) {
            continue;
        }

        QPointF mapPos(x, y);
        QPointF screenPos = pointTransform(mapPos);

        // 检测点击距离
        double distance = QLineF(pos, screenPos).length();
        if (distance <= clickRadius) {
            emit agvClicked(agvNumber, mapPos);
            return;
        }
    }
}

} // namespace presentation
